using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Diagnostics;

using Advent.aiDevices;


namespace Advent.Controls
{
    public partial class DeviceCtrl : UserControl
    {
        public DeviceCtrl()
        {
            InitializeComponent();
            tab_Main.SelectedIndexChanged += new EventHandler(tab_Main_SelectedIndexChanged);
            tab_Main_SelectedIndexChanged(this, EventArgs.Empty);
        }

        /// <summary>
        /// This handles when the main tab index has changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void tab_Main_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                TabControl T = sender as TabControl;
                if (T == null) return;
                foreach (TabPage page in T.TabPages)
                {
                    bool En = (page == T.SelectedTab);
                    foreach (Control ctrl in page.Controls)
                    {
                        ctrl.Enabled = En;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        
        /// <summary>
        /// This must return a reference to the device which is 
        /// used within this form
        /// </summary>
        protected virtual aiDevice GetDeviceReference()
        {
            return null;
        }
        
        /// <summary>
        /// responds to the Connect button click
        /// </summary>
        private void btn_Connect_Click(object sender, EventArgs e)
        {
            try
            {
                List<Exception> _Errors = new List<Exception>();
                // If we are somehow already connected, abort
                aiDevice Dev = GetDeviceReference();
                if ((Dev != null) && (Dev.IsConnected)) return;

                // Don't allow re-entrancy to this call
                btn_Connect.Enabled = false;
                btn_Disconnect.Enabled = false;
                tab_Main.Enabled = false;


                if (rb_ConnectToAnthing.Checked)
                {
                    // Here we try to connect to any available device 
                    Connect(null);
                }
                else if (rb_ConnectToSerial.Checked)
                {
                    // Here we try to connect to a device with a particular serial number
                   Connect(txt_ConnectSerial.Text);
                }

                if (GetDeviceReference() == null) throw new Exception("No devices found");


                // intialize the form based on device settings
                InitializeFormFromDevice();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                UpdateControlStates();
                tab_Main_SelectedIndexChanged(tab_Main, EventArgs.Empty);
            }
            
        }
        /// <summary>
        /// This should be overloaded by derived classes to respond to the Connect
        /// button click
        /// </summary>
        protected virtual void Connect(String Serial)
        {


        }

        /// <summary>
        /// This updates the current UI state based on the device connection status
        /// </summary>
        private void UpdateControlStates()
        {
            try
            {

                aiDevice dev = GetDeviceReference();
                Boolean Connected = ((dev != null) && (dev.IsConnected));
                btn_Connect.Enabled = !Connected;
                btn_Disconnect.Enabled = Connected;
                tab_Main.Enabled = Connected;
                gb_Status.Enabled = Connected;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// This must be overriden such that it can be instantiated 
        /// </summary>
        protected virtual void InitializeFormFromDevice()
        {
            try
            {
                aiDevice Dev = GetDeviceReference();
                if (Dev == null)
                {
                    UpdateControlStates();
                    return;
                }
                GenCtrl.SetDevice(Dev as HALFirmwareDevice);
                lbl_Serial.Text = Dev.SerialNumber;
                HALFirmwareDevice D = Dev as HALFirmwareDevice;
                if (D != null)
                {
                    lbl_FirmwareVersion.Text = D.Info.FirmwareVersion;
                }
                else
                {
                    lbl_FirmwareVersion.Text = "(unavailable)";
                }
            }
            catch { }
        }

        private void btn_Disconnect_Click(object sender, EventArgs e)
        {
            try
            {
                aiDevice Dev = GetDeviceReference();
                if (Dev != null)
                {
                    Dev.Close();   // This actually terminates all device communications
                }
            }
            finally
            {
                UpdateControlStates();
            }
        }

        private void DeviceCtrl_Load(object sender, EventArgs e)
        {
            try
            {
                UpdateControlStates();
            }
            catch { }
        }
    }
}
